
from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client
from django.conf import settings
from tracer.local_settings import TENCENT_COS_ID, TENCENT_COS_KEY
from sts.sts import Sts
from django.http import JsonResponse

"""
    腾讯云新创建账户的密钥：
        SecretId:AKIDqUu52qPjoeHfnZDgutd8NN8evxkIchXA
        SecretKey:RecOxJQIwKUQ7Zu1uYx73kCSYT9bogLl
"""
# 创建腾讯云的桶
def create_bucket(bucket,region="ap-guangzhou"):
       # region = 'ap-guangzhou'      # 替换为用户的 region，已创建桶归属的 region 可以在控制台查看，https://console.cloud.tencent.com/cos5/bucket
    config = CosConfig(Region=region, SecretId=settings.TENCENT_COS_ID, SecretKey=settings.TENCENT_COS_KEY) # 初始化对象
    client = CosS3Client(config) # 实例化初始化的对象
    client.create_bucket(
        Bucket=bucket, # 桶的名字
        # ACL = 'public-read'
        # ACL='private'
    )
    # 创建规则，解决跨域问题CORS。在上面创建完桶时会自动创建这个规则
    cors_config = {
        'CORSRule':[
            {
                'ID':'1001',
                'AllowedOrigin':'*',
                'AllowedMethod': ['GET','PUT','HEAD','POST','DELETE'],
                'AllowedHeader': '*',
                'ExposeHeader': '*',
                'MaxAgeSeconds': 500
            }
        ]
    }
    client.put_bucket_cors(
        Bucket=bucket,
        CORSConfiguration=cors_config
    )

# secret_id = 'AKIDqUu52qPjoeHfnZDgutd8NN8evxkIchXA'     # 临时密钥的 SecretId，临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048
# secret_key = 'RecOxJQIwKUQ7Zu1uYx73kCSYT9bogLl'   # 临时密钥的 SecretKey，临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048
# # token = None               # 临时密钥的 Token，临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048
# region = 'ap-guangzhou'      # 替换为用户的 region，已创建桶归属的 region 可以在控制台查看，https://console.cloud.tencent.com/cos5/bucket
#                            # COS 支持的所有 region 列表参见https://cloud.tencent.com/document/product/436/6224
# # scheme = 'https'           # 指定使用 http/https 协议来访问 COS，默认为 https，可不填
# config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key) # 初始化对象
# client = CosS3Client(config) # 实例化初始化的对象
# # 使用实例化的对象来上传文件
# response = client.create_bucket(
#         Bucket="7777-1334110564", # 桶的名字
#         ACL = 'public-read'
#     )

def put_object(bucket,region,key,image_object):
    """ 上传文件 """
    config = CosConfig(Region=region, SecretId=settings.TENCENT_COS_ID, SecretKey=settings.TENCENT_COS_KEY) # 初始化对象
    client = CosS3Client(config) # 实例化初始化的对象
    client.put_object(
        Bucket=bucket, # 桶的名字，在网页中建立的桶
        Key=key,  # 上传到桶之后的文件名
        Body=image_object,
    )
    # https://17899999999-2025-02-07-1334110564.cos.ap-guangzhou.myqcloud.com/%E4%B8%8B%E8%BD%BD%E5%B0%8F%E5%8A%A9%E6%89%8B.jpg
    return "https://{}.cos.{}.myqcloud.com/{}".format(bucket,region,key)

def delete_file(bucket,region,key):
    """ 单个删除桶中的文件 """
    config = CosConfig(Region=region, SecretId=settings.TENCENT_COS_ID, SecretKey=settings.TENCENT_COS_KEY) # 初始化对象
    client = CosS3Client(config) # 实例化初始化的对象
    client.delete_object(
        Bucket=bucket, # 要删除文件的桶的名字
        Key=key,  # 要删除的文件的名字
    )

def delete_file_list(bucket,region,key_list):
    """ 单个删除桶中的文件 """
    config = CosConfig(Region=region, SecretId=settings.TENCENT_COS_ID, SecretKey=settings.TENCENT_COS_KEY) # 初始化对象
    client = CosS3Client(config) # 实例化初始化的对象
    objects = {
        "Quiet": "true",
        "Object": key_list
    }
    client.delete_objects(
        Bucket=bucket, # 要删除文件的桶的名字
        Delete=objects,  # 要删除的文件的名字
    )


def credential(bucket,region):
    """获取临时的凭证"""
    config = {
        # 临时凭证的有效时间，单位是秒
        'duration_seconds': 1800,
        # 固定密钥id
        'secret_id': TENCENT_COS_ID,
        # 固定密钥key
        'secret_key': TENCENT_COS_KEY,
        # 桶名称
        'bucket': bucket,
        # 桶所在的区域
        'region': region,
        'allow_prefix': '*',
        # 临时凭证所拥有的权限,有上传、更新、删除等等
        'allow_actions': [
            'name/cos:PutObject',
            # 'name/cos:PostObject',
            # 'name/cos:DeleteObject',
            # 'name/cos:UploadPart',
            # 'name/cos:UploadPartCopy',
            # 'name/cos:CompleteMultipartupload',
            # 'name/cos:AbortMultipartupload',
            # '*',
        ],
    }
    # 根据配置建立Sts对象的实例
    sts = Sts(config)
    # 通过实例化的对象来获取凭证
    result_dict = sts.get_credential()
    # 返回Json格式的凭证数据
    return result_dict

# 从COS端取数据，验证上传的文件是否正确
def check_file(bucket,region,key):
    """ 单个删除桶中的文件 """
    config = CosConfig(Region=region, SecretId=settings.TENCENT_COS_ID, SecretKey=settings.TENCENT_COS_KEY) # 初始化对象
    client = CosS3Client(config) # 实例化初始化的对象
    data = client.head_object(
        Bucket=bucket, # 要删除文件的桶的名字
        Key=key,  # 要删除的文件的名字
    )
    return data

# 执行删除桶的操作
def delete_bucket(bucket,region):
    """ 删除桶"""
    config = CosConfig(Region=region,SecretId=settings.TENCENT_COS_ID, SecretKey=settings.TENCENT_COS_KEY)
    client = CosS3Client(config)
    # 找到桶中所有的文件
    while True:
        part_objects = client.list_objects(bucket)
        # 因为每次最多返回1000个文件，所以可以用这个数据来判断是否还有剩余文件，Contents没有数据时代表文件被全部取完了
        contents = part_objects.get('Contents')
        if not contents:
            break
        # # 也可以用COS自带的方法判断，判断文件是不是截断的，如果不是即值为：false，那么就代表数据全部取完了，就可以退出循环了
        # if part_objects['IsTruncated'] == 'false':
        #     break
        # 把每次获取到的文件进行批量删除。"Object": 这个数据的格式是列表中套着一个个的字典，所以可以自己利用列表生成式来手动生成一个字典
        objects = {
            "Quiet": "true",
            "Object": [{'Key':item['Key']} for item in contents]
        }
        client.delete_objects(
            Bucket=bucket,  # 要删除文件的桶的名字
            Delete=objects,  # 要删除的文件的名字
        )
        # 把这个方法放在最后就可以少执行一次，获取文件的操作。节约性能资源
        # 用COS自带的方法判断，判断文件是不是截断的，如果不是即值为：false，那么就代表数据全部取完了，就可以退出循环了
        if part_objects['IsTruncated'] == 'false':
            break
    # 找到桶中的碎片文件并删除
    while True:
        # 获取桶中所有的碎片
        part_uploads = client.list_multipart_uploads(bucket)
        uploads = part_uploads.get('Upload') # Upload中保存有碎片数据，如果这里面没数据了代表碎片全部取完了，从而退出循环
        if not uploads:
            break
        # 循环清除碎片文件
        for item in uploads:
            client.abort_multipart_upload(bucket,item['Key'],item['UploadId'])
        # 还是判断是否是截断状态，如果不是则直接跳出循环即可
        if part_uploads['IsTruncated'] == 'false':
            break

    # 文件和碎片全部删除后，直接删除桶就可以了
    client.delete_bucket(bucket)
















